package com.google.code.mamule.order;

import com.google.code.mamule.integration.PricingStrategyHolder;
import com.google.code.mamule.mail.Mail;
import com.google.code.mamule.price.PricingStrategy;
import com.google.code.mamule.user.User;
import com.google.common.base.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PostLoad;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * Created with IntelliJ IDEA. User: borck_000 ; Date: 12/23/13 ; Time: 12:13 AM
 */
@Entity
@Table(name = "T_ORDER")
public class Order {

  private final static Logger log = LoggerFactory.getLogger(Order.class);

  public static enum State {
    TRANSIENT, CONFIRMED;
  }

  @Id
  @GeneratedValue
  private Long id;

  @ManyToOne(fetch = FetchType.EAGER)
  private User owner;

  @Temporal(TemporalType.TIMESTAMP)
  private Date date = new Date();
  @Enumerated(EnumType.STRING)
  private State state = State.TRANSIENT;
  private BigDecimal total = BigDecimal.ZERO;

  @OneToMany(fetch = FetchType.EAGER)
  private Set<Mail> items;

  public Order() {
  }

  @Override
  public String toString() {
    return Objects.toStringHelper(this)
        .add("owner", owner)
        .add("status", state)
        .add("date", date)
        .add("total", total)
        .add("items", items)
        .toString();
  }

  @PostLoad
  private void updatePrice() {
    if (this.state == State.CONFIRMED) {
      return;
    }
    log.debug("UPDATING PRICE ON " + this);
    PricingStrategy pricer = PricingStrategyHolder.get();
    total = BigDecimal.ZERO;
    for (Mail each : this.getItems()) {
      total = total.add(pricer.apply(each));
    }
  }

  public Long getId() {
    return id;
  }

  public void setId(final Long id) {
    this.id = id;
  }

  public User getOwner() {
    return owner;
  }

  public void setOwner(final User owner) {
    this.owner = owner;
  }

  public Date getDate() {
    return date;
  }

  public void setDate(final Date date) {
    this.date = date;
  }

  public State getState() {
    return state;
  }

  public void setState(final State state) {
    this.state = state;
  }

  public BigDecimal getTotal() {
    return total;
  }

  public void setTotal(final BigDecimal total) {
    this.total = total;
  }

  public Set<Mail> getItems() {
    return items;
  }

  public void setItems(final Set<Mail> items) {
    this.items = items;
  }
}
